
/******************************************************************************
*@file  : app.c
*@brief : application
******************************************************************************/

#include "app.h" 

volatile uint32_t g_extiLine = 0;


/******************************************************************************
*@brief : EXTI interrupt callback function
*@param : Line: EXTI Line
*@return: None
******************************************************************************/
void HAL_EXTI_LineCallback(uint32_t Line)
{
    uint8_t i;
	for(i = 0; i < 21; i++)
	{
		if (Line & 0x01)
		{
			g_extiLine = i;
		}
		Line >>= 1;
		if(Line == 0)
		{
			break;
		}
			
	}
}

/******************************************************************************
*@brief : wake-up configuration
*@param : mode: Low power consumption mode selection
*@return: None
******************************************************************************/
void Wakeup_Init(uint8_t mode)
{
    GPIO_InitTypeDef GPIO_PINx_Handle;
    
    if(mode == PMU_POWERDOWN_MODE)
    {
        //HAL_PMU_WakeupIOInit(PMU_WAKEUP1);            
        //HAL_PMU_WakeupIOInit(PMU_WAKEUP2);
        HAL_PMU_WakeupIOInit(PMU_WAKEUP3);      
    }
    else
    {       
        __HAL_RCC_EXTI_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /*---------------------------EXTI_Line12-----------------------------*/  	
        /* Initialization GPIO */
        GPIO_PINx_Handle.Pin       = GPIO_PIN_12;
        GPIO_PINx_Handle.Mode      = GPIO_MODE_INPUT;
        GPIO_PINx_Handle.Pull      = GPIO_NOPULL;
        GPIO_PINx_Handle.Drive     = GPIO_DRIVE_LEVEL3;
        HAL_GPIO_Init(GPIOB, &GPIO_PINx_Handle);

        /* Config EXTI */
        HAL_EXTI_SetConfigLine((GPIO_TypeDef *)GPIOB, EXTI_LINE_12, EXTI_MODE_IT_RISING);
        NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
        NVIC_SetPriority(EXTI15_10_IRQn, 5);
        NVIC_EnableIRQ(EXTI15_10_IRQn);
    }

}

/******************************************************************************
*@brief : Sleep mode.
*@param : mode:WAIT_FOR_INT or WAIT_FOR_EVENT
*@return: None
******************************************************************************/
void Sleep_Mode(uint32_t mode)
{
    printfS("MCU enter Sleep mode \r\n");
    __set_PRIMASK(1);    // disable interrupt 
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     // disable systick  
    SCB->ICSR = BIT25;   // clear systick pending bit
    
    /* Enter Sleep */
    HAL_PMU_EnterSleep(mode); 
    
    __set_PRIMASK(0);    // enable interrupt
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;  // enable systick                               
    printfS("MCU exti Sleep! Wakeup by EXTI_LINE_%d\r\n", g_extiLine);        
}

/******************************************************************************
*@brief : Stop mode.
*@param : mode:WAIT_FOR_INT or WAIT_FOR_EVENT
*@return: None
******************************************************************************/
void Stop_Mode(uint32_t mode)
{
    printfS("MCU enter Stop mode \r\n");
    __set_PRIMASK(1);    // disable interrupt 
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     // disable systick 
    SCB->ICSR = BIT25;   // clear systick pending bit 
    
    /* Enter Stop */
    //HAL_PMU_EnterStop(mode);
    extern void Enter_Stop_RunInSRAM(void);
    Enter_Stop_RunInSRAM();
    
    __set_PRIMASK(0);    // enable interrupt
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;  // enable systick                   
}


/******************************************************************************
*@brief : Standby mode.
*@param : mode:WAIT_FOR_INT or WAIT_FOR_EVENT
*@return: None
******************************************************************************/
void Powerdown_Mode(uint32_t mode)
{
    printfS("MCU enter Powerdown mode \r\n");        
    __set_PRIMASK(1);    // disable interrupt
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;     // disable systick 
    SCB->ICSR = BIT25;   // clear systick pending bit  
    
    /* Enter Standby */
    //HAL_PMU_EnterPowerdownMode(mode);
    
    extern void Enter_Powerdown_RunInSRAM(void);
    Enter_Powerdown_RunInSRAM();
    
    __set_PRIMASK(0);    // enable interrupt  
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;  // enable systick            
                
    while(1)
    {
        printfS("MCU never run here \r\n");
    }
}


/******************************************************************************
*@brief : Low power test.
*@param : mode: Low power consumption mode selection
*@return: None
******************************************************************************/
void APP_LowPower_Mode_Test(uint8_t mode)
{
    printfS("Low power test\r\n");
    
    HAL_PMU_Init();
    
    HAL_Delay(2500);
    
    Wakeup_Init(mode);
    
    switch(mode)
    {
        /* sleep mode */
        case PMU_SLEEP_MODE:
        {  
            while(1)
            {
                Sleep_Mode(WAIT_FOR_INT);          
                g_extiLine = 0;
                HAL_Delay(2500);
            }
        }
         /* stop mode */
        case PMU_STOP_MODE:
        {
            while(1)
            {       
                Stop_Mode(WAIT_FOR_INT);
                HAL_Init();  
                SystemClock_Config(SYSCLK_180M_SRC_RC64M, RCC_PCLK1_DIV_1, RCC_PCLK2_DIV_1); 
                BSP_UART_Init(UART1);
                printfS("MCU exti Stop! Wakeup by EXTI_LINE_%d\r\n", g_extiLine);
                g_extiLine = 0;
                HAL_Delay(2500);
            }
        }
      
        /* Powerdown mode */
        case PMU_POWERDOWN_MODE:
        {           
            Powerdown_Mode(WAIT_FOR_INT);
        }
        default:
            printfS("he application is not supported!\r\n");
        break;

    }
    
}



